//
//  WKWebViewController.swift
//  HHSwift
//
//  Created by 华宏 on 2019/10/21.
//  Copyright © 2019 huahong. All rights reserved.
//

import UIKit
import WebKit
import JavaScriptCore

class WKWebViewController: BaseViewController,WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler {
    
    

    var webView:WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        title = "WKWebView"
        
        let optionURL = Bundle.main.url(forResource: "h5", withExtension: "html")
        guard let url = optionURL else { return  }
        let request = URLRequest(url: url)
        
        //配置
        let config = WKWebViewConfiguration()
        
        //true: 使用h5的视频播放器在线播放, false:使用原生播放器全屏播放
        config.allowsInlineMediaPlayback = true
        
         //设置音视频是否需要用户手动播放
        config.mediaTypesRequiringUserActionForPlayback = .all
        
        //设置是否允许画中画技术 在特定设备上有效
        config.allowsPictureInPictureMediaPlayback = true
        
        let preference = WKPreferences()
        config.preferences = preference

        //最小字体
        preference.minimumFontSize = 40
        
        //设置是否支持javaScript 默认是支持的
        preference.javaScriptEnabled = true
        
        //是否允许不经过用户交互由javaScript自动打开窗口,默认为NO
        preference.javaScriptCanOpenWindowsAutomatically = false
        
        //这个类主要用来做native与JavaScript的交互管理
        let userContentController = WKUserContentController()
        config.userContentController = userContentController

         /** JS调OC */
        self.JSCallOC("share", userContentController: userContentController)
        
        /** 注入JS */
        let jsString = "alert(\"WKUserScript注入js\");"
        self.injectJS(jsString, userContentController: userContentController)
        
        
        self.webView = WKWebView(frame: self.view.bounds, configuration: config)
        self.webView.uiDelegate = self //UI代理
        self.webView.navigationDelegate = self //导航代理
        self.webView.allowsBackForwardNavigationGestures = true //允许手势返回
        self.webView.load(request)
        self.view.addSubview(self.webView)
        
       
        
        
    }
 
    //MARK: - JS注入
    
    /// JS注入
    /// - Parameters:
    ///   - jsString: 将要注入的JS字符串
    ///   - userContentController: userContentController
    func injectJS(_ jsString:String,userContentController:WKUserContentController) -> Void {
        
        //NO(全局窗口)，yes（只限主窗口）
      let userScript = WKUserScript(source: jsString, injectionTime: .atDocumentStart, forMainFrameOnly: true)
        userContentController.addUserScript(userScript)
        
        
//       let userInfo = ["name": "wb", "sex": "male", "phone": "12333434"]
//        let jsonData = try? JSONSerialization.data(withJSONObject: userInfo, options: .prettyPrinted)
//        let jsonText = String.init(data: jsonData!, encoding: String.Encoding.utf8)
//
//        //注入对象
//        let script = WKUserScript.init(source: "var userInfo = \(jsonText!)", injectionTime: .atDocumentStart, forMainFrameOnly: true)
//
//        //注入函数
//        let script = WKUserScript.init(source: "var iOSApp = {\"getUserInfo\":function(){return \(jsonText!)}}", injectionTime: .atDocumentStart, forMainFrameOnly: true)
//
//        userContentController.addUserScript(script)
        
//        也可以通过WebView的evaluateJavaScript方法实现注入

    }
 
    
    //MARK: - 原生调JS
    func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil) {
     
        //原生调JS
       self.webView.evaluateJavaScript(javaScriptString) { (obj, error) in
          completionHandler?(obj,error)
       }
        
//          webView.evaluateJavaScript("var iOSApp = {\"getUserInfo\":function(){return \(jsonText!)}}", completionHandler: nil)

    }
    

    //MARK: - JS调OC
    
    func JSCallOC(_ methodName:String,userContentController:WKUserContentController) -> Void {
        userContentController.add(self, name: methodName)
    }
    
    //MARK: - WKScriptMessageHandler
    //JS调OC，再此回调
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
        
        if message.name == "share" {
            print("body:\(message.body)")
        }
    }
    
   
    //MARK: - WKNavigationDelegate ：主要处理一些跳转、加载处理操作
       // 页面开始加载时调用
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        
    }
   
      // 页面加载失败时调用
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        
    }
    
        // 当内容开始返回时调用
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        
    }
   
        // 页面加载完成之后调用
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        
    }
    
        //提交发生错误时调用
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
//        [self.progressView setProgress:0.0f animated:NO];
        
    }
    
       // 接收到服务器跳转请求即服务重定向时之后调用
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        
    }
    
        // 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        let _ = navigationAction.request.url?.absoluteString;
               
        decisionHandler(.allow);
               
    }
   
        
        // 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        
        let urlStr = navigationResponse.response.url?.absoluteString
        print("urlStr:\(String(describing: urlStr))")
         //允许跳转
        decisionHandler(.allow)
        
        //不允许跳转
//        decisionHandler(.cancel)
        
        
        
    }

    //需要响应身份验证时调用 同样在block中需要传入用户身份凭证
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
     
        //用户身份信息
//           NSURLCredential * newCred = [[NSURLCredential alloc] initWithUser:@"user123" password:@"123" persistence:NSURLCredentialPersistenceNone];
//           //为 challenge 的发送方提供 credential
//           [challenge.sender useCredential:newCred forAuthenticationChallenge:challenge];
//           completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
    }
    
        //进程被终止时调用
    func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        
    }
    

    //MARK: - WKUIDelegate ：主要处理JS脚本，确认框，警告框等
    /**
         *  web界面中有弹出警告框时调用
         *
         *  @param webView           实现该代理的webview
         *  @param message           警告框中的内容
         *  @param completionHandler 警告框消失调用
         */
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        let alertController = UIAlertController(title: "OC调JS的弹出框", message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler()
        }))
        
        self.present(alertController, animated: true, completion: nil)
        
    }
    
        // 确认框
        //JavaScript调用confirm方法后回调的方法 confirm是js中的确定框，需要在block中把用户选择的情况传递进去
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        
        let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler(true)
        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) in
             completionHandler(false)
                   
               }))
               
        self.present(alertController, animated: true, completion: nil)
    }
    
        // 输入框
        //JavaScript调用prompt方法后回调的方法 prompt是js中的输入框 需要在block中把用户输入的信息传入
    func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        
        let alertController = UIAlertController(title: prompt, message: nil, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
            completionHandler(alertController.textFields?.first?.text)
        }))
        alertController.addTextField { (textField) in
            textField.text = defaultText
        }
               
        self.present(alertController, animated: true, completion: nil)
    }
    
        // 页面是弹出窗口 _blank 处理
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        
        if (navigationAction.targetFrame?.isMainFrame != nil) {
              webView.load(navigationAction.request)
            }
              
        return nil;
    }
   
    //MARK: -
    override func topRightAction() {
          
        self.evaluateJavaScript("showAlert('huahong')") { (obj, error) in
            
        }
     }
    
    deinit {
        
        self.webView.configuration.userContentController.removeScriptMessageHandler(forName: "share")
        
    }
}
